﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.Runtime.Serialization;

namespace Galaktika.BI.Silverlight.ClientApp
{
    [XmlRoot(Namespace = Common.Namespace)]
    [DataContract(Namespace = Common.Namespace)]
    public class InvokeSchema
    {
        public InvokeSchema()
        {
            m_Args = new List<InvokeArg>();
        }

        public InvokeSchema(string commandId)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>();
        }

        public InvokeSchema(string commandId, IDictionary<string, string> args)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>();
            foreach (KeyValuePair<string, string> kv in args)
            {
                this.Args.Add(new InvokeArg(kv.Key, kv.Value));
            }
        }

        public InvokeSchema(string commandId, IEnumerable<InvokeArg> args)
        {
            if (string.IsNullOrEmpty(commandId))
            {
                throw new ArgumentNullException("commandId");
            }
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            this.CommandId = commandId;
            m_Args = new List<InvokeArg>(args);
        }

        [XmlElement]
        [DataMember]
        public string CommandId { get; set; }

        private List<InvokeArg> m_Args;
        [XmlArray]
        [XmlArrayItem(typeof(InvokeArg))]
        [DataMember]
        public List<InvokeArg> Args 
        {
            get
            {
                return m_Args;
            }
        }

        private Dictionary<string, string> m_Cache;
        private void EnsureCache()
        {
            if (m_Cache == null)
            {
                m_Cache = new Dictionary<string, string>();
                foreach (InvokeArg arg in this.Args)
                {
                    m_Cache.Add(arg.Name, arg.Value);
                }
            }
        }

        [XmlIgnore]
        [IgnoreDataMember]
        public string this[string name]
        {
            get
            {
                this.EnsureCache();
                string res;
                m_Cache.TryGetValue(name, out res);

                return res;
            }
        }

        [XmlIgnore]
        [IgnoreDataMember]
        public IDictionary<string, string> AsDictionary
        {
            get
            {
                this.EnsureCache();

                return m_Cache;
            }
        }
    }

    [XmlRoot(Namespace = Common.Namespace)]
    [DataContract(Namespace = Common.Namespace)]
    public class InvokeArg
    {
        public InvokeArg()
        {
        }

        public InvokeArg(string name, string value)
        {
            this.Name = name;
            this.Value = value;
        }

        [XmlElement]
        [DataMember]
        public string Name { get; set; }

        [XmlElement]
        [DataMember]
        public string Value { get; set; }
    }

    public class KnownInvokeArgs
    {
        public readonly static string ContextId = "ContextId";
        public readonly static string DataSourceId = "DataSourceId";
        public readonly static string Path = "Path";
    }
}
